package com.buddy.leetcode._07;

/**
 * 给定一个 32 位有符号整数，将整数中的数字进行反转。
 * 示例 1:
 *      输入: 123
 *      输出: 321
 * 示例 2:
 *      输入: -123
 *      输出: -321
 * 示例 3:
 *      输入: 120
 *      输出: 21
 * 注意:
 * 假设我们的环境只能存储 32 位有符号整数，
 * 其数值范围是 [−2^31,  2^31 − 1]。
 * 根据这个假设，如果反转后的整数溢出，则返回 0。
 */
public class ReverseInteger {

    /**
     * int 数据类型是32位、有符号的以二进制补码表示的整数；
     * 最小值是 -2,147,483,648（-2^31）；
     * 最大值是 2,147,483,647（2^31 - 1）；
     * 一般地整型变量默认为 int 类型；
     *
     * 思路：
     *      重复“弹出” x 的最后一位数字，并将它“推入”到 rev的后面。
     *      最后，rev 将与 x 相反
     * @param x 待反转数字
     * @return rev 反转后的数字
     *
     * 当x为正数时，
     * 如果 temp=rev*10+pop 导致溢出，那么一定有 rev≥Integer.MAX_VALUE/10​​，
     *      当 rev>Integer.MAX_VALUE/10,那么temp = rev*10+pop一定会溢出；
     *      当 rev=Imteger.MAX_VALUE/10,那么temp = rev*10+pop当pop>7时，一定会溢出
     */
    public int reverse(int x) {
        int rev = 0;
        int pop = 0;
        while(x != 0){
            pop = x%10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE/10 && pop > 7)){
                return 0;
            }
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE/10 && pop < -8)){
                return 0;
            }
            rev = rev *10 + pop;
        }
        return rev;
    }

    /**
     * 使用long类型来处理int问题，这样就不会存在溢出了
     * 但，最后要判断(int)long转换时是否存在溢出
     * @param i
     * @return
     */
    public int reverse_2(int i){
        long rev = 0;
        long x = i;
        boolean isPository = false;
        if (0 > x){
            isPository = true;
            x = (-1)*x;
        }
        while (x != 0){
            rev = rev*10 + x%10;
            x /= 10;
        }
        //如果是正数，且大于MAV_VALUE，返回0
        if (!isPository && rev > Integer.MAX_VALUE) return 0;
        //如果是负数，且小于MIN_VALUE，返回0
        if (isPository){
            rev = -1* rev;
            if (rev < Integer.MIN_VALUE){
                return 0;
            }
        }
        return (int) rev;
    }

    private int reverse_3(int x) {
        int res = 0;
        while (x !=0){
            if (Math.abs(res)>Integer.MAX_VALUE/10) return 0;
            if ((Math.abs(res)==Integer.MAX_VALUE/10) && (Math.abs(x)%10 > 7)) return 0;
            res = res*10 + x%10;
            x/=10;
        }
        return res;
    }


    private static int reverse_4(int x) {
        long rev = 0;
        while (x != 0){
            rev = rev*10 + x%10;
            x /=10;
        }
        if (rev > Integer.MAX_VALUE || rev < Integer.MIN_VALUE) return 0;
        return (int) rev;
    }

    public static void main(String[] args){
        int x = 123;
        System.out.println(reverse_4(x));
    }


}
